import G6 from '@antv/g6';
import {deepClone} from '@/plugins/utils';
export const NodeBorderColors = [
    '#7F86FF',
    '#5B8FF9',
    '#5AD8A6',
    '#5D7092',
    '#AE6CFF',
    '#FF5A34',
    '#5D7092',
    '#FF6565',
    '#6BFFDE',
    '#7DA8FF',
    '#44E6C1',
    '#FF68A7'
];
export const edgeColors = [
    '#FFA1E3',
    '#FFE269',
    '#BFCFEE',
    '#FFA0C5',
    '#D5FF86',
    '#8FE9FF',
    '#87EAEF',
    '#FFC9E3',
    '#A7C2FF',
];
let nodesMap = new Map(); // 所有事件节点，key:nodeId,value:nodeItem
let reasonMap = null; 
// 配置文件
function sizeConfig(step){
    // 默认是step<60
    let eventNodeConfig = {
        style:{
            width:30,
            height:15,
            lineWidth: 0.5,
            radius:2
        },
        anchorPoints: [
            [0.5, 0],
            [1, 0.5],
            [0.5, 1],
            [0, 0.5]
          ],
        labelCfg: {
            position:'top',
            offset:0,
            style: {
                fill: '#495057',
                fontSize: 2,
            },
        }
    };
    let timeNodeConfig = {
        r:2,
        labelCfg: {
            position:'bottom',
            offset:4,
            style:{
                fontSize:4
            },
            icon:{
                show:true,
                width:2,
                height:2
            }
        }
    };
    if(step >= 60 && step < 90){
        eventNodeConfig.style.width = 46;
        eventNodeConfig.style.height = 36;
        eventNodeConfig.labelCfg.style.fontSize = 4.5;
        timeNodeConfig.r = 2;
        timeNodeConfig.labelCfg.style.fontSize = 5;
        timeNodeConfig.labelCfg.offset = 6;
    }else if(step >= 90 && step < 120){
        eventNodeConfig.style.width = 62;
        eventNodeConfig.style.height = 40;
        eventNodeConfig.labelCfg.style.fontSize = 6;
        timeNodeConfig.r = 2;
        timeNodeConfig.labelCfg.style.fontSize = 6;
        timeNodeConfig.labelCfg.offset = 10;
    }else if(step >= 120){
        eventNodeConfig.style.width = 73
        eventNodeConfig.style.height = 59;
        eventNodeConfig.labelCfg.style.fontSize = 6.5;
        timeNodeConfig.r = 2;
        timeNodeConfig.labelCfg.style.fontSize = 6;
        timeNodeConfig.labelCfg.offset = 10;
    };
    return {
        eventNodeConfig,
        timeNodeConfig
    }
}
// 单行文字超长时用省略号替换
/**
 * @description: 
 * @param {*} str       需要转换文本
 * @param {*} maxWidth  单行最大长度
 * @param {*} fontSize  字体大小
 * @return {*}
 */
export function fittingStringByEllopsis(str, maxWidth, fontSize){
    const ellipsis = "...";
    const ellipsisLength = G6.Util.getTextSize(ellipsis, fontSize)[0];
    let currentWidth = 0;
    let res = str;
    const pattern = new RegExp("[\u4E00-\u9FA5]+"); // distinguish the Chinese charactors and letters
    str.split("").forEach((letter, i) => {
      if (currentWidth > maxWidth - ellipsisLength) return;
      if (pattern.test(letter)) {
        // Chinese charactors
        currentWidth += fontSize;
      } else {
        // get the width of single letter according to the fontSize
        currentWidth += G6.Util.getLetterWidth(letter, fontSize);
      }
      if (currentWidth > maxWidth - ellipsisLength) {
        res = `${str.substr(0, i)}${ellipsis}`;
      }
    });
    return res;
  };
  // 多行文字高度超出边框省略
/**
 * @description: 
 * @param {*} str        需要转换的文本
 * @param {*} maxWidth   单行最大长度
 * @param {*} maxHeight  最大高度
 * @param {*} fontSize   字体大小
 * @return {*}
 */
export function fittingString(str, maxWidth, maxHeight, fontSize){
    let currentWidth = 0;
    let currentHeight = 0;
    // let res = '';
    let res = [];
    let isCut = false;
    const pattern = new RegExp('[\u4E00-\u9FA5]+'); // distinguish the Chinese charactors and letters
    let cutOutIndexs = []; // 换行的索引
    str.split('').forEach((letter, i) => {
        if (currentWidth > maxWidth) return;
        if (pattern.test(letter)) {
            // Chinese charactors
            currentWidth += fontSize;
        } else {
            // get the width of single letter according to the fontSize
            currentWidth += G6.Util.getLetterWidth(letter, fontSize);
            // console.log(G6.Util.getLetterHeight(letter,fontSize))
        }
        if(currentWidth >= maxWidth){
            currentWidth = 0;
            cutOutIndexs.push(i);
        }
    });
    
    // 多行时
    if(cutOutIndexs.length){
        cutOutIndexs.reduce((prevIndex,curIndex,index)=>{
            currentHeight += fontSize;
            if(currentHeight <= maxHeight){
                res.push(str.substring(prevIndex,curIndex));
                if(index === cutOutIndexs.length - 1 && index < str.length - 1){
                    if(currentHeight + fontSize < maxHeight){
                        res.push(str.substr(curIndex));
                    }else{
                        let lastLineStr = fittingStringByEllopsis(res[res.length-1],maxWidth,fontSize);
                        console.log(lastLineStr)
                        res.pop();
                        res.push(lastLineStr)
                    }
                }
            }else if(!isCut){
                isCut = true;
                let lastLineStr = fittingStringByEllopsis(res[res.length-1],maxWidth,fontSize);
                res.pop();
                res.push(lastLineStr)
            }
            return curIndex;
        },0);
    }else{
    // 单行时
        res = [str];
    }
    return res.join('\n');
  };

// 创建时间节点
/**
 * @description: 
 * @param {*} width   canvas画布剩余宽度
 * @param {*} height  canvas画布高度
 * @param {*} data    新增节点列表
 * @param {*} step    节点间剧
 * @return {*}
 */
function createTimeNodes(width,height,data,step,timeNodeConfig){
    let timeNodes = []; // 时间节点
    for(let i=0;i<data.length;i++){
        let timeItem = Object.assign({},timeNodeConfig);
        timeItem.id = data[i].id;
        timeItem.label = data[i].eventTime;
        // timeItem.level = data[i].level;
        // timeItem.column = data[i].column;
        timeItem.column = i + 1;
        timeItem.x = width - step * (i + 1);
        // timeItem.x = width - step * (i) - step / 2;
        timeItem.y = height - 50;
        timeItem.events = data[i].events.map(event=>event.id);
        data[i].x = timeItem.x;  // 保留当前时间节点的x和y坐标，供创建事件节点使用。
        data[i].y = timeItem.y;
        timeItem.type = 'time-node';
        if(i === data.length-1){
            timeItem.Madd = true;
            timeItem.icon = {
                show:true,
                width:2,
                height:2,
                text:'i'
            }
        }else{
            timeItem.icon = {}
        }
        timeNodes.push(timeItem);
    }
    return timeNodes;
}

// 创建时间连线
/**
 * @description: 
 * @param {*} timeNodes  时间节点列表
 * @return {*}
 */
function createTimeLines(timeNodes){
    let timeEdges = [];
    timeNodes.reduce((prev,current)=>{
        let edgeItem = {
            style:{
                lineWidth:0.5
            }
        };
        if(prev){
            edgeItem.id = `${prev.id}-${current.id}`;
            edgeItem.source = prev.id;
            edgeItem.target = current.id;
            // edgeItem.level = prev.level;
            edgeItem.sourceColumn = prev.column;
            edgeItem.targetColumn = current.column;
            edgeItem.edgeType="horizontal-timeline"
            timeEdges.push(edgeItem);
        }
        return current;
    },null);
    return timeEdges;
}

// 创建事件节点和竖向连线
/**
 * @description: 
 * @param {*} data 原始数据
 * @param {*} step 相邻两时间节点间距
 * @param {*} eventNodeConfig 默认事件节点配置
 * @return {*}
 */
function createEventNodesAndVerticalEdges(data,step,eventNodeConfig){
    let eventNodes = []; // 所有的事件节点列表
    let verticalEdges = [];  // 所有的竖向线
    let levelStep = step;  // 相邻时间节点间距
    let arrowEdges = []; // 所有的关系连线列表
    let list = data.list;
    let lines = data.lines;
    let weight = 1;
    for(let i=0;i<list.length;i++){
        let events = list[i].events;
        let column = i + 1;
        
        if(events.length){
            for(let j=0;j<events.length;j++){
                let row = j + 1;
                let eventNodeItem = Object.assign({},eventNodeConfig);
                eventNodeItem.type = 'event-node';
                eventNodeItem.id = events[j].id;
                eventNodeItem.containt = events[j].containt;
                eventNodeItem.abstract = events[j].abstract;
                eventNodeItem.reasonType = events[j].reasonType;
                transferReasonType(eventNodeItem.reasonType);
                // eventNodeItem.level = events[j].level;
                // eventNodeItem.column = events[j].column;
                eventNodeItem.column = column;
                eventNodeItem.row = row;
                // eventNodeItem.weight = events[j].weight;
                eventNodeItem.weight = weight++;
                eventNodeItem.x = list[i].x;
                eventNodeItem.y = list[i].y - levelStep * (j+1) + levelStep / 3;
                eventNodeItem.time = list[i].eventTime;
                eventNodeItem.timeId = list[i].id;
                eventNodeItem.step = levelStep;
                eventNodeItem.target = events[j].target;
                eventNodes.push(eventNodeItem);
                nodesMap.set(eventNodeItem.id,eventNodeItem);
                if(!events[j-1]){
                    let verticalEdgeItem = {
                        style:{
                            lineWidth:0.5
                        }
                    };
                    // verticalEdgeItem.style.lineWidth = 1;
                    verticalEdges.edgeType = 'vertical-timeline';
                    verticalEdgeItem.target = events[j].id;
                    // verticalEdgeItem.source = events[j-1] ? events[j-1].id : data[i].id;
                    verticalEdgeItem.source = list[i].id;
                    verticalEdgeItem.id = `${verticalEdgeItem.source}-${verticalEdgeItem.target}`;
                    // verticalEdgeItem.level = events[j].level;
                    verticalEdgeItem.column = events[j].column;
                    // verticalEdgeItem.style.endArrow = events[j-1] ? true : false;
                    verticalEdges.push(verticalEdgeItem);
                }
            }
        }
    }
    arrowEdges = transferEdges(lines);
    return {eventNodes,verticalEdges,arrowEdges};
}
function transferReasonType(reasonType){
    reasonType.forEach(reason=>{
        let reasonTypeId = reason.id;
        reason.color = reasonMap.get(reasonTypeId).color;
    })
}
export function transferEdges(originEdges){
    let arrowEdges = [];
    originEdges.forEach(item=>{
        let {sourceId,targetId,relationship,reverseRelationship,twoWay} = item;
        let source = nodesMap.get(sourceId);
        let target = nodesMap.get(targetId);
        let arrowEdge = defineArrowEdge(source,target,twoWay,relationship,reverseRelationship);
        arrowEdge && arrowEdges.push(arrowEdge);
    })
    return arrowEdges;
}
export function transferNodes(nodeIds){
    let nodes = [];
    nodeIds.forEach(nodeId=>{
        let node = nodesMap.get(nodeId);
        nodes.push(node)
    })
    return nodes;
}
// 定义关系连接线
/**
 * @description: 
 * @param {*} sourceNode  连接线起始节点
 * @param {*} targetNode  连接线终止节点
 * @param {*} isTowWay    是否是双箭头
 * @param {*} relationship 由左指向右的关系，标在连线上方
 * @param {*} reverseRelationship 由右指向左关系，标在连线下方
 * @return {*}
 */
export function defineArrowEdge(sourceNode,targetNode,isTowWay=false,relationship=undefined,reverseRelationship=undefined){
    if(!sourceNode || !targetNode){
        return;
    }
    let arrowEdge = {};
    arrowEdge.type = 'event-arrow';
    arrowEdge.source = sourceNode.id;
    arrowEdge.target = targetNode.id;
    arrowEdge.id = `${arrowEdge.source}-${arrowEdge.target}`;
    // arrowEdge.level = sourceNode.level;
    arrowEdge.offset = (sourceNode.step - sourceNode.style.width)/3;
    arrowEdge.eventNodeWidth = sourceNode.style.width;
    arrowEdge.eventNodeHeight = sourceNode.style.height;
    arrowEdge.step = sourceNode.step;
    arrowEdge.sourceColumn = sourceNode.column;  // 由
    arrowEdge.targetColumn = targetNode.column;
    arrowEdge.sourceRow = sourceNode.row;
    arrowEdge.targetRow = targetNode.row;
    arrowEdge.sourceWeight = sourceNode.weight;
    arrowEdge.targetWeight = targetNode.weight;
    let { sourceAnchor, targetAnchor } = calculateAnchor(arrowEdge);
    arrowEdge.sourceAnchor = sourceAnchor;
    arrowEdge.targetAnchor = targetAnchor;
    arrowEdge.isTowWay = isTowWay;
    arrowEdge.relationship = relationship;
    arrowEdge.reverseRelationship = reverseRelationship;
    arrowEdge.fontSize = sourceNode.labelCfg.style.fontSize;
    return arrowEdge;
}
// 定义连线对应连接点
/**
 * @description: 
 * @param {*} edge 自定义连接线对象
 * @return {*}
 */
function calculateAnchor(edge){
    let {sourceColumn,targetColumn,sourceRow,targetRow,sourceWeight,targetWeight} = edge;
    let sourceAnchor,targetAnchor;
    if((sourceColumn === targetColumn || sourceRow === targetRow) && Math.abs(sourceWeight - targetWeight) === 1){ 
        // 指相邻的两个事件间连线
        return {sourceAnchor,targetAnchor};
    }else if(Math.abs(sourceColumn - targetColumn) === 1){
        // 相邻两列事件连线
        sourceAnchor = sourceColumn > targetColumn ? 1 : 3;
        targetAnchor = targetColumn > sourceColumn ? 1 : 3;
        return {sourceAnchor,targetAnchor};
    }else if(sourceRow === targetRow && Math.abs(sourceWeight - targetWeight) > 1){
        // 行数相同但不相邻
        sourceAnchor = 2;
        targetAnchor = 2;
        return {sourceAnchor,targetAnchor};
    }else if(sourceColumn === targetColumn && Math.abs(sourceWeight - targetWeight) > 1){
        console.log('dfjie')
        // 列数相同但不相邻
        sourceAnchor = 1;
        targetAnchor = 1;
        return {sourceAnchor,targetAnchor};
    }else{
        // 行列都不相同
        sourceAnchor = sourceColumn > targetColumn ? 1 : 3;
        targetAnchor = sourceColumn > targetColumn ? 3 : 1;
        return {sourceAnchor,targetAnchor};
    }
}

/**
 * @description: 
 * @param {*} width // 画布总宽
 * @param {*} height // 画布总高
 * @param {*} showNums // 已展示时间节点个数
 * @param {*} addDatas  // 新增时间节点数据
 * @return {*}
 */    
export function stepCreateNodes(width,height,showNums,addDatas,reasonTypeMap){
    reasonMap = reasonTypeMap;
    // console.log('addDatas',addDatas)
    let _data = deepClone(addDatas);
    let nums = _data.list.length;       // 最多展示时间节点个数
    let padding = 50;    // 画布左右两侧留白
    let step = Math.floor((width - padding * 2) / nums);
    let remainWidth = width - showNums * step; // 画布剩余宽度
    let { eventNodeConfig, timeNodeConfig } = sizeConfig(step);
    let timeNodes = createTimeNodes(remainWidth,height,_data.list,step,timeNodeConfig);  // 新增时间节点列表
    let timeEdges = createTimeLines(timeNodes);  // 新增时间轴连线
    let { eventNodes,verticalEdges,arrowEdges } = createEventNodesAndVerticalEdges(_data,step,eventNodeConfig); // 新增事件节点和竖向连线
    // console.log('timeNodes',timeNodes)
    // console.log('timeEdges',timeEdges)
    // console.log('eventNodes',eventNodes)
    // console.log('verticalEdges',verticalEdges)
    // console.log('arrowEdges',arrowEdges)
    let data = {
        nodes:[
            ...timeNodes,
            ...eventNodes
        ],
        edges:[
            ...timeEdges,
            ...verticalEdges,
            ...arrowEdges,
        ]
    }
    return data;
    
    
}
